<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
    <link rel="icon" type="image/jpeg" sizes="80x80" href="/imgs/logo.jpg" />
    <title>Json View</title>
    <style type="text/css">
        .jv-json-txt {
            height: 90vh !important;
        }

        .jv-json-view {
            max-height: 90vh !important;
            overflow: auto;
        }
    </style>
</head>

<body>

    <div id="root"></div>

    <link rel="stylesheet" href="../cdn/bootswatch/bootstrap.morphme.min.css" />
    <link href="../cdn/font-awesome-4.7.0/css/font-awesome.min.css" rel="stylesheet" />

    <script src="../cdn/react/react.production.min.js"></script>
    <script src="../cdn/react/react-dom.production.min.js"></script>
    <script src="../cdn/react/babel.min.js"></script>
    <script src="../cdn/react/react-json-view.js"></script>
    <script src="../cdn/dexie.min.js"></script>
    <script type="text/babel">

        let storage_jsontxt_key = "pages-jsonview-jsontxt";
        let dbName = 'yanhui';
        var db = new Dexie(dbName);
        db.version(1).stores({
            jsonview: "++id,title,data"
        });

        ReactDOM.render(
            <AppRoot />,
            document.getElementById('root')
        );

        let pageSize = 10;
        function AppRoot() {

            let storageTxt = localStorage.getItem(storage_jsontxt_key);
            if (!storageTxt) storageTxt = "{}";
            let [jsonTxt, setJsonTxt] = React.useState(storageTxt);
            let [data, setData] = React.useState({});
            let [jsonList, setJsonList] = React.useState([]);
            let [selectedHis, setSelectedHis] = React.useState('');
            let [fileName, setFileName] = React.useState('');
            let [count, setCount] = React.useState(0);
            let [currentPage, setCurrentPage] = React.useState(1);
            let updatedSrc = {};

            React.useEffect(() => {
                initJsonTree();
                initHis(currentPage);
            }, [])

            function initHis(page) {
                db.transaction('rw', db.jsonview, async () => {
                    let dataCount = await db.jsonview.count();
                    setCount(dataCount);
                    const dbJsonList = await db.jsonview.offset((page - 1) * pageSize).limit(pageSize).reverse().toArray();
                    setJsonList(dbJsonList);
                    setCurrentPage(page);
                }).catch(e => {
                    alert(e.stack || e);
                });
            }

            function initJsonTree() {
                updatedSrc = JSON.parse(jsonTxt);
                setData(updatedSrc);
            }

            function jsonChange(value) {
                if (!value) value = "{}";
                localStorage.setItem(storage_jsontxt_key, value);
                setJsonTxt(value);
                setData(JSON.parse(value));
            }

            function getJsonTxt() {
                setJsonTxt(JSON.stringify(updatedSrc, null, 4));
            }

            function modifyEvent(e) {
                updatedSrc = e.updated_src;
                setJsonTxt(JSON.stringify(updatedSrc, null, 4));
            }

            async function saveJson() {
                await db.jsonview.add({ data, title: fileName === '' ? new Date().toLocaleString() : fileName });
                setFileName('');
                initHis(currentPage);
            }

            function selectHis(json) {
                setSelectedHis(json.title);
                jsonChange(JSON.stringify(json.data, null, 4));
            }

            function lastPage() {
                if (currentPage === 1) {
                    return;
                }
                initHis(currentPage - 1);
            }

            function nextPage() {
                if (currentPage * pageSize > count) {
                    return;
                }
                initHis(currentPage + 1);
            }

            function clearHis() {
                if (count === 0) return;
                if (!confirm('确认删除所有历史记录?')) return;
                db.transaction('rw', db.jsonview, async () => {
                    await db.jsonview.limit(1000).reverse().delete();
                    initHis();
                }).catch(e => {
                    alert(e.stack || e);
                });
            }

            return (
                <div>
                    <nav class="navbar navbar-expand-lg navbar-light bg-light">
                        <div class="container-fluid">
                            <div class="navbar-brand" href="#">
                                <h2><i class="fa fa-camera text-primary"></i> <span>Json View</span></h2>
                            </div>
                        </div>
                    </nav>
                    <div class="container-fluid">
                        <div class="row p-1 mt-2">
                            <div class="col-md-5">
                                <textarea placeholder="请输入json字符串" class="form-control jv-json-txt border border-primary rounded" onChange={e => jsonChange(e.target.value)} value={jsonTxt}></textarea>
                            </div>
                            <div class="col-md-5 p-2 jv-json-view border border-primary rounded">
                                <reactJsonView.default src={data}
                                    onEdit={modifyEvent}
                                    onAdd={modifyEvent}
                                    onDelete={modifyEvent}
                                    displayDataTypes={false} />
                            </div>
                            <div class="col-md-2 bg-light p-1 jv-json-view">
                                <div>
                                    <button type="button" class="btn btn-primary mb-2" onClick={saveJson}>Save Json To IndexedDB</button>
                                    <input value={fileName} onChange={(e) => { setFileName(e.target.value) }} class="form-control" type="text" placeholder="请输入保存的JSON名称" />
                                </div>
                                {
                                    count > 0 &&
                                    <div>
                                        <h3 class="my-3">Json History</h3>
                                        {
                                            count > pageSize &&
                                            <div class="m-1 p-1 d-flex justify-content-around">
                                                <button type="button" class="btn btn-primary mb-2" onClick={lastPage}>Last</button>
                                                <button type="button" class="btn btn-primary mb-2" onClick={nextPage}>Next</button>
                                            </div>
                                        }

                                        <div class="list-group mt-2">
                                            {
                                                jsonList.map(json => {
                                                    return (
                                                        <a href="#" onClick={() => selectHis(json)} class={`list-group-item list-group-item-action ${selectedHis === json.title ? 'active' : ''}`}>{json.title}</a>
                                                    )
                                                })
                                            }
                                        </div>
                                        <div class="m-1">
                                            <small>当前历史数据一共 <b class="text-danger">{count}</b> 条,第 <b class="text-danger">{currentPage}</b> 页</small>
                                        </div>
                                        <div class="m-1 p-1 d-flex justify-content-around">
                                            <button type="button" class="btn btn-primary mb-2" onClick={clearHis}>ClearHis</button>
                                        </div>
                                    </div>
                                }

                            </div>
                        </div>
                    </div>

                </div>
            )

        }


    </script>
</body>

</html>